package models

import (
	"time"

	"fmt"
	"github.com/Unknwon/com"
	"github.com/astaxie/beego"
	"github.com/astaxie/beego/orm"
	_ "github.com/go-sql-driver/mysql"
	"os"
	"path"
	"strconv"
	"strings"
)

const (
	_DB_NAME      = "data/beeapp.db"
	_MYSQL_DRIVER = "mysql"
)

//func init(){
//	orm.RegisterDriver("mysql",orm.DRMySQL)//注册驱动
//}

func RegisterDB() {
	if !com.IsExist(_DB_NAME) { // 是否存在这个
		os.MkdirAll(path.Dir(_DB_NAME), os.ModePerm) //逐层递归创建  目录  文件外侧
		os.Create(_DB_NAME)                          // 创建文件
	}

	dbUser := beego.AppConfig.String("mysqluser")
	dbName := beego.AppConfig.String("mysqldb") //数据库名字
	dbPwd := beego.AppConfig.String("mysqlpass")
	dbLink := fmt.Sprintf("%s:%s@/%s?charset=utf8", dbUser, dbPwd, dbName)
	orm.DefaultTimeLoc = time.Local
	orm.RegisterModel(new(Category), new(Topic), new(Comment))

	orm.RegisterDriver(_MYSQL_DRIVER, orm.DRMySQL)                 // 注册model
	orm.RegisterDataBase("default", _MYSQL_DRIVER, dbLink, 10, 30) //用户名:密码@数据库地址+名称?字符集 (test数据库提前建好)

}

type Category struct {
	Id              int64     //  有id int  就是自增主键
	Title           string    //255 字节
	Created         time.Time `orm:"index"` //tag  反射使用  可反射 首字母 需要大写
	views           int64     `orm:"index"` //见表的时候 给我加索引
	TopicTime       time.Time `orm:"index"`
	TopicCount      int64
	TopicLastUserId int64
}

type Topic struct {
	Id               int64
	Uid              int64
	Title            string
	Category         string
	Labels           string
	Content          string `orm:"size(5000)"` // 不够用  5000  m默认
	Attachment       string
	Created          int64 `orm:"index"`
	Updated          int64 `orm:"index"`
	View             int64
	Author           string
	ReplyTime        int64 `orm:"index"` // 回复时间=
	ReplyCount       int64
	ReplayLastUserId int64
}

type Comment struct {
	Id      int64
	Tid     int64
	Name    string
	Content string `orm:"size(1000)"`
	Created int64  `orm:"index"`
}

func AddTopic(title, category,label, content,attachment string) error {
	//"beego orm"
	//\|/
	//[beego orm]

	//\|/
	// $beego#$orm#

	label = "$" + strings.Join( strings.Split(label," "),"#$") +"#"  //   strings.Join  将切片 串成字符串 二参 是 拼接 字符 这里是 “#$”

	o := orm.NewOrm()

	topic := &Topic{
		Title:    title,
		Content:  content,
		Labels:    label,
		Attachment: attachment,
		Category: category,
		Created:  int64(time.Now().Unix()),
		Updated:  time.Now().Unix(),
	}

	_, err := o.Insert(topic)

	if err != nil {
		return err
	}

	//更新分类统计
	cate := new(Category) // 获得一个分类对象
	qs := o.QueryTable("category")
	err = qs.Filter("title", category).One(cate) // 找到需要操作的分类

	if err == nil {
		//如果存在
		cate.TopicCount++  //
		_, err = o.Update(cate)

	} //不存在 就忽略更新操作

	return err

}

func ModifyTopic(title, category, label,content, tid,attachmentname string) error {

	fmt.Print("wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww")
	tidNum, err := strconv.ParseInt(tid, 10, 64)
	fmt.Printf("%v",tid)
	if err != nil {
		return err
	}

	fmt.Print("qqqqqqqqqqqqqqqqqqqqqqqqq")
	label = "$" + strings.Join( strings.Split(label," "),"#$") +"#"  //   strings.Join  将切片 串成字符串 二参 是 拼接 字符 这里是 “#$”

	o := orm.NewOrm()
	topic := &Topic{Id: tidNum} //新建结构 id 赋值进去
	var oldCate ,oldAttach string  // 多个文件同一个 文件  要 注意

	fmt.Print("ddddddddddddddddddddd")

	if o.Read(topic) == nil { // read 回去找 id 非零的
		fmt.Print("55555555555555555555555")
		oldCate = topic.Category  //取到的旧的 存一下
		oldAttach = topic.Attachment  //取到的旧的 存一下
		topic.Title = title
		topic.Labels = label
		topic.Content = content
		topic.Category = category
		topic.Updated = time.Now().Unix()

		if len(attachmentname)>0{
			topic.Attachment = attachmentname
		}
		_, err := o.Update(topic)

		if err != nil{
			return err
		}


	}

	fmt.Printf("%v",oldCate)
	fmt.Print(oldCate)
	//更新分类统计

	if len(oldCate) > 0 {

		cate := new(Category)
		qs := o.QueryTable("category")
		err := qs.Filter("title", oldCate).One(cate)
		if err == nil {
			cate.TopicCount--
			_, err = o.Update(cate)
		}
	}else{
		fmt.Println("没有老分类")
	}

	//删除这个旧附件
	if len(oldAttach)>0{
		os.Remove(path.Join("attachment",oldAttach))
	}

	cate := new(Category)
	qs := o.QueryTable("category")
	err = qs.Filter("Title", category).One(cate)

	if err == nil {
		cate.TopicCount++
		_, err = o.Update(cate)
	}

	return err
}

func AddReply(tid, name, content string) error {
	tidNum, err := strconv.ParseInt(tid, 10, 64)
	if err != nil {
		return err
	}

	reply := &Comment{
		Tid:     tidNum,
		Name:    name,
		Content: content,
		Created: time.Now().Unix(),
	}

	o := orm.NewOrm()
	_, err = o.Insert(reply)
	if err !=nil{
		return err
	}

	topic := &Topic{Id:tidNum}  //获得一个 topic 对想  就会根据 Id  获取相应的数据
	if o.Read(topic) == nil{
		topic.ReplyCount++
		topic.ReplyTime = time.Now().Unix()
		_, err = o.Update(topic)
		return  err

	}
	return err

}

func DelReply(rid string) error {
	ridNum, err := strconv.ParseInt(rid, 10, 64) // 进制 位大小

	if err != nil {
		return err
	}
	o := orm.NewOrm()

	var tidNum  int64
	reply := &Comment{Id: ridNum} // 查找记录

	if o.Read(reply) ==nil{
		tidNum = reply.Tid;
	}

	_, err = o.Delete(reply) //必须主键

	if err != nil{
		return err
	}

	replies  := make([]*Comment,0)

	qs := o.QueryTable("comment")

	_,err = qs.Filter("tid",tidNum).OrderBy("-created").All(&replies)

	if err != nil{
		return err
	}

	topic := &Topic{Id:tidNum}

	if o.Read(topic) == nil{
		topic.ReplyTime = replies[0].Created
		topic.ReplyCount = int64(len(replies))   // len 默认 是  int
		_,err = o.Update(topic)
	}



	return err
}

func GetAllReplies(tid string) (replies []*Comment, err error) {
	tidNum, err := strconv.ParseInt(tid, 10, 64)
	if err != nil {
		return nil, err
	}

	replies = make([]*Comment, 0) // 因不知 10 - 20
	o := orm.NewOrm()

	qs := o.QueryTable("comment")

	_, err = qs.Filter("tid", tidNum).All(&replies) // 全部结果 复制到 replies

	return replies, err

}

func AddCategory(name string) error {
	o := orm.NewOrm()

	cate := &Category{Title: name}

	qs := o.QueryTable("category")

	fmt.Print("找下")
	err := qs.Filter("title", name).One(cate)

	if err == nil { // 找到了  没错
		fmt.Print("没找到")
		return err //返回 nil
	}
	fmt.Print("没找到下一一步---")
	cate.Created = time.Now()
	cate.TopicTime = time.Now()
	_, err = o.Insert(cate)

	if err != nil {
		return err
	}

	return nil

}

func GetAllCategories() ([]*Category, error) {
	o := orm.NewOrm()

	cates := make([]*Category, 0)

	qs := o.QueryTable("category")

	_, err := qs.All(&cates)

	return cates, err
}

func GetAllTopics(cid string, label string,isDesc bool) ([]*Topic, error) {
	o := orm.NewOrm()
	topics := make([]*Topic, 0)

	qrs := o.QueryTable("topic")
	var err error

	if isDesc {
		if len(cid) > 0 {
			qrs.Filter("category", cid) //错的
			qrs = qrs.Filter("category", cid)
		}
		if len(label)>0{
			qrs = qrs.Filter("labels__contains", "$"+label+"#")
		}
		_, err = qrs.OrderBy("-created").All(&topics) //  数据库 全部会转成小写
	} else {
		_, err = qrs.All(&topics)
	}

	return topics, err
}

func GetTopicinfo(id string) (*Topic, error) {
	tidNum, err := strconv.ParseInt(id, 10, 64) // 数据库 中 是 int64

	if err != nil {
		return nil, err
	}

	o := orm.NewOrm() // orm 对象

	topic := new(Topic)         //
	qs := o.QueryTable("topic") //

	err = qs.Filter("id", tidNum).One(topic)

	if err != nil {
		return nil, err
	}


	topic.View++
	_, err = o.Update(topic)
	topic.Labels =strings.Replace( strings.Replace(topic.Labels,"#"," ",-1),"$","",-1)    // 一定放在之后    再改写成空格 不然存进去了  -1代表 无数次

	return topic, err

}

func DelCategory(id string) error {
	cid, err := strconv.ParseInt(id, 10, 64) // 进制 位大小

	if err != nil {
		return err
	}
	o := orm.NewOrm()

	cate := &Category{Id: cid}

	_, err = o.Delete(cate) //必须主键

	return err
}

func DelTopic(id string) error {
	tid, err := strconv.ParseInt(id, 10, 64)

	if err != nil {
		return err
	}
	var oldCate string
	o := orm.NewOrm()

	topic := &Topic{Id: tid}

	if o.Read(topic) == nil{
		oldCate=topic.Category
		_,err = o.Delete(topic)
		if err != nil{
			return err
		}
	}

	if len(oldCate)>0{
		cate := new(Category)
		qs := o.QueryTable("category")
		err = qs.Filter("Title",oldCate).One(cate)

		if err == nil{
			cate.TopicCount--
			_,err = o.Update(cate)

		}
	}
	return err
}
